home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / adainc / i-c.adb < prev    next >
Text File  |  1996-01-30  |  10KB  |  386 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                         I N T E R F A C E S . C                          --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.6 $                              --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. with System;
  27. with Unchecked_Conversion;
  28.  
  29. package body Interfaces.C is
  30.  
  31.    -----------------------
  32.    -- Is_Nul_Terminated --
  33.    -----------------------
  34.  
  35.    --  Case of char_array
  36.  
  37.    function Is_Nul_Terminated (Item : in char_array) return Boolean is
  38.    begin
  39.       for J in Item'Range loop
  40.          if Item (J) = nul then
  41.             return True;
  42.          end if;
  43.       end loop;
  44.  
  45.       return False;
  46.    end Is_Nul_Terminated;
  47.  
  48.    --  Case of wchar_array
  49.  
  50.    function Is_Nul_Terminated (Item : in wchar_array) return Boolean is
  51.    begin
  52.       for J in Item'Range loop
  53.          if Item (J) = wide_nul then
  54.             return True;
  55.          end if;
  56.       end loop;
  57.  
  58.       return False;
  59.    end Is_Nul_Terminated;
  60.  
  61.    ------------
  62.    -- To_Ada --
  63.    ------------
  64.  
  65.    --  Convert char_array to String (function form)
  66.  
  67.    function To_Ada
  68.      (Item     : in char_array;
  69.       Trim_Nul : in Boolean := True)
  70.       return     String
  71.    is
  72.       Count : Natural;
  73.       From  : size_t;
  74.  
  75.    begin
  76.       if Trim_Nul then
  77.          From := Item'First;
  78.  
  79.          loop
  80.             exit when Item (From) = nul;
  81.  
  82.             if From = Item'Last then
  83.                raise Terminator_Error;
  84.             else
  85.                From := From + 1;
  86.             end if;
  87.          end loop;
  88.  
  89.          Count := Natural (From - Item'First);
  90.  
  91.       else
  92.          Count := Item'Length;
  93.       end if;
  94.  
  95.       declare
  96.          subtype Return_Type is String (1 .. Count);
  97.          type Return_Type_Ptr is access Return_Type;
  98.          function To_Return_Type_Ptr is
  99.            new Unchecked_Conversion (System.Address, Return_Type_Ptr);
  100.  
  101.       begin
  102.          return To_Return_Type_Ptr (Item'Address).all;
  103.       end;
  104.    end To_Ada;
  105.  
  106.    --  Convert char_array to String (procedure form)
  107.  
  108.    procedure To_Ada
  109.      (Item       : in char_array;
  110.       Target     : out String;
  111.       Count      : out Natural;
  112.       Trim_Nul   : in Boolean := True)
  113.    is
  114.       From   : size_t;
  115.  
  116.    begin
  117.       if Trim_Nul then
  118.          From := Item'First;
  119.          loop
  120.             exit when Item (From) = nul;
  121.  
  122.             if From = Item'Last then
  123.                raise Terminator_Error;
  124.             else
  125.                From := From + 1;
  126.             end if;
  127.          end loop;
  128.  
  129.          Count := Natural (From - Item'First);
  130.  
  131.       else
  132.          Count := Item'Length;
  133.       end if;
  134.  
  135.       if Count > Target'Length then
  136.          raise Constraint_Error;
  137.  
  138.       else
  139.          From := Item'First;
  140.          for To in Target'Range loop
  141.             Target (To) := Character (Item (From));
  142.             From := From + 1;
  143.          end loop;
  144.       end if;
  145.  
  146.    end To_Ada;
  147.  
  148.    --  Convert wchar_array to Wide_String (function form)
  149.  
  150.    function To_Ada
  151.      (Item     : in wchar_array;
  152.       Trim_Nul : in Boolean := True)
  153.       return     Wide_String
  154.    is
  155.       Count : Natural;
  156.       From  : size_t;
  157.  
  158.    begin
  159.       if Trim_Nul then
  160.          From := Item'First;
  161.  
  162.          loop
  163.             exit when Item (From) = wide_nul;
  164.  
  165.             if From = Item'Last then
  166.                raise Terminator_Error;
  167.             else
  168.                From := From + 1;
  169.             end if;
  170.          end loop;
  171.  
  172.          Count := Natural (From - Item'First);
  173.  
  174.       else
  175.          Count := Item'Length;
  176.       end if;
  177.  
  178.       declare
  179.          subtype Return_Type is Wide_String (1 .. Count);
  180.          type Return_Type_Ptr is access Return_Type;
  181.          function To_Return_Type_Ptr is
  182.            new Unchecked_Conversion (System.Address, Return_Type_Ptr);
  183.  
  184.       begin
  185.          return To_Return_Type_Ptr (Item'Address).all;
  186.       end;
  187.    end To_Ada;
  188.  
  189.    --  Convert wchar_array to Wide_String (procedure form)
  190.  
  191.    procedure To_Ada
  192.      (Item       : in wchar_array;
  193.       Target     : out Wide_String;
  194.       Count      : out Natural;
  195.       Trim_Nul   : in Boolean := True)
  196.    is
  197.       From   : size_t;
  198.  
  199.    begin
  200.       if Trim_Nul then
  201.          From := Item'First;
  202.          loop
  203.             exit when Item (From) = wide_nul;
  204.  
  205.             if From = Item'Last then
  206.                raise Terminator_Error;
  207.             else
  208.                From := From + 1;
  209.             end if;
  210.          end loop;
  211.  
  212.          Count := Natural (From - Item'First);
  213.  
  214.       else
  215.          Count := Item'Length;
  216.       end if;
  217.  
  218.       if Count > Target'Length then
  219.          raise Constraint_Error;
  220.  
  221.       else
  222.          From := Item'First;
  223.          for To in Target'Range loop
  224.             Target (To) := Wide_Character (Item (From));
  225.             From := From + 1;
  226.          end loop;
  227.       end if;
  228.  
  229.    end To_Ada;
  230.  
  231.    ----------
  232.    -- To_C --
  233.    ----------
  234.  
  235.    --  Convert String to char_array (function form)
  236.  
  237.    function To_C
  238.      (Item       : in String;
  239.       Append_Nul : in Boolean := True)
  240.       return       char_array
  241.    is
  242.       Length : size_t;
  243.  
  244.    begin
  245.       --  If appending null, we have to make a copy
  246.  
  247.       if Append_Nul then
  248.          declare
  249.             Target : char_array (0 .. Item'Length);
  250.             To     : size_t;
  251.  
  252.          begin
  253.             To := 0;
  254.             for From in Item'Range loop
  255.                Target (To) := char (Item (From));
  256.                To := To + 1;
  257.             end loop;
  258.  
  259.             Target (Item'Length) := nul;
  260.             return Target;
  261.          end;
  262.  
  263.       --  If not appending null, we can use unchecked conversion to return
  264.       --  the result, since we know in GNAT there is structural equivalence.
  265.  
  266.       else
  267.          declare
  268.             subtype Return_Type is char_array (0 .. Item'Length - 1);
  269.             type Return_Type_Ptr is access Return_Type;
  270.             function To_Return_Type_Ptr is
  271.               new Unchecked_Conversion (System.Address, Return_Type_Ptr);
  272.  
  273.          begin
  274.             return To_Return_Type_Ptr (Item'Address).all;
  275.          end;
  276.       end if;
  277.    end To_C;
  278.  
  279.    --  Convert String to char_array (procedure form)
  280.  
  281.    procedure To_C
  282.      (Item       : in String;
  283.       Target     : out char_array;
  284.       Count      : out size_t;
  285.       Append_Nul : in  Boolean := True)
  286.    is
  287.       To : size_t;
  288.  
  289.    begin
  290.       if Target'Length < Item'Length then
  291.          raise Constraint_Error;
  292.  
  293.       else
  294.          To := Target'First;
  295.          for From in Item'Range loop
  296.             Target (To) := char (Item (From));
  297.             To := To + 1;
  298.          end loop;
  299.  
  300.          if Append_Nul then
  301.             if To > Target'Last then
  302.                raise Constraint_Error;
  303.             else
  304.                Target (To) := nul;
  305.             end if;
  306.          end if;
  307.       end if;
  308.    end To_C;
  309.  
  310.    --  Convert Wide_String to wchar_array (function form)
  311.  
  312.    function To_C
  313.      (Item       : in Wide_String;
  314.       Append_Nul : in Boolean := True)
  315.       return       wchar_array
  316.    is
  317.       Length : size_t;
  318.  
  319.    begin
  320.       --  If appending null, we have to make a copy
  321.  
  322.       if Append_Nul then
  323.          declare
  324.             Target : wchar_array (0 .. Item'Length);
  325.             To     : size_t;
  326.  
  327.          begin
  328.             To := 0;
  329.             for From in Item'Range loop
  330.                Target (To) := wchar_t (Item (From));
  331.                To := To + 1;
  332.             end loop;
  333.  
  334.             Target (Item'Length) := wide_nul;
  335.             return Target;
  336.          end;
  337.  
  338.       --  If not appending null, we can use unchecked conversion to return
  339.       --  the result, since we know in GNAT there is structural equivalence.
  340.  
  341.       else
  342.          declare
  343.             subtype Return_Type is wchar_array (0 .. Item'Length - 1);
  344.             type Return_Type_Ptr is access Return_Type;
  345.             function To_Return_Type_Ptr is
  346.               new Unchecked_Conversion (System.Address, Return_Type_Ptr);
  347.  
  348.          begin
  349.             return To_Return_Type_Ptr (Item'Address).all;
  350.          end;
  351.       end if;
  352.    end To_C;
  353.  
  354.    --  Convert Wide_String to wchar_array (procedure form)
  355.  
  356.    procedure To_C
  357.      (Item       : in Wide_String;
  358.       Target     : out wchar_array;
  359.       Count      : out size_t;
  360.       Append_Nul : in  Boolean := True)
  361.    is
  362.       To : size_t;
  363.  
  364.    begin
  365.       if Target'Length < Item'Length then
  366.          raise Constraint_Error;
  367.  
  368.       else
  369.          To := Target'First;
  370.          for From in Item'Range loop
  371.             Target (To) := wchar_t (Item (From));
  372.             To := To + 1;
  373.          end loop;
  374.  
  375.          if Append_Nul then
  376.             if To > Target'Last then
  377.                raise Constraint_Error;
  378.             else
  379.                Target (To) := wide_nul;
  380.             end if;
  381.          end if;
  382.       end if;
  383.    end To_C;
  384.  
  385. end Interfaces.C;
  386.